{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.Series对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1Series对象创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    1\n",
      "1    2\n",
      "2    3\n",
      "3    4\n",
      "dtype: int64\n",
      "<class 'pandas.core.series.Series'>\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from pandas import Series,DataFrame\n",
    "import numpy as np \n",
    "\n",
    "sel =  Series([1,2,3,4])\n",
    "print(sel) \n",
    "print(type(sel)) #pandas.core.series.Series'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "[1 2 3 4]\n",
      "Index(['a', 'b', 'c', 'd'], dtype='object')\n",
      "[('a', 1), ('b', 2), ('c', 3), ('d', 4)]\n"
     ]
    }
   ],
   "source": [
    "# 创建Series对象并省略索引\n",
    "'''\n",
    "index 参数是可省略的，你可以选择不输入这个参数。\n",
    "如果不带 index 参数，Pandas 会自动用默认 index 进行索引，类似数组，索引值是 [0, ..., len(data) - 1]\n",
    "'''\n",
    "sel =  Series(data = [1,2,3,4], index = ['a','b','c','d']) \n",
    "sel =  Series(data = [1,2,3,4], index = list('abcd')) \n",
    "\n",
    "print(sel)\n",
    "# 获取内容\n",
    "print(sel.values)\n",
    "# 获取索引\n",
    "print(sel.index)\n",
    "# 获取索引和值对\n",
    "print(list(sel.iteritems())) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "red      100\n",
      "black    400\n",
      "green    300\n",
      "pink     900\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# 将字典转换为Series\n",
    "dict={\"red\":100,\"black\":400,\"green\":300,\"pink\":900}\n",
    "se3 = Series(dict)\n",
    "print(se3)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2Series对象获取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "********************\n",
      "根据位置下标和索引下标获取\n",
      "索引下标 3\n",
      "位置下标 3\n"
     ]
    }
   ],
   "source": [
    "# Series数据获取\n",
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "\n",
    "print(\"*\"*20)\n",
    "print(\"根据位置下标和索引下标获取\")\n",
    "print('索引下标',sel['c'])\n",
    "print('位置下标',sel[2]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "********************\n",
      "获取不连续的数据  获取不连续的数据必须传入列表 \n",
      "索引下标 a    1\n",
      "c    3\n",
      "dtype: int64\n",
      "位置下标 b    2\n",
      "d    4\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Series数据获取\n",
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "\n",
    "print(\"*\"*20)\n",
    "print(\"获取不连续的数据  获取不连续的数据必须传入列表 \")\n",
    "print('索引下标',sel[['a','c']])\n",
    "print('位置下标',sel[[1,3]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "********************\n",
      "切片获取数据\n",
      "位置切片 b    2\n",
      "c    3\n",
      "dtype: int64\n",
      "索引切片 b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Series数据获取\n",
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "print(\"*\"*20)\n",
    "print(\"切片获取数据\")\n",
    "print('位置切片',sel[1:3])  #左闭右开\n",
    "print('索引切片',sel['b':'d']) #左闭右闭"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3Series对象数据修改"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "d    1\n",
      "c    2\n",
      "b    3\n",
      "a    4\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "# 重新赋值索引的值 \n",
    "sel.index = list('dcba')\n",
    "print(sel) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "b    2.0\n",
      "a    1.0\n",
      "c    3.0\n",
      "d    4.0\n",
      "e    NaN\n",
      "dtype: float64\n",
      "b     2\n",
      "a     1\n",
      "c     3\n",
      "d     4\n",
      "e    10\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "# 将标签索引重新排序 \n",
    "print(sel.reindex(index=['b','a','c','d','e']))\n",
    "print(sel.reindex(index=['b','a','c','d','e'],fill_value=10))  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    10\n",
      "1    11\n",
      "2    12\n",
      "3    13\n",
      "4    14\n",
      "dtype: int64\n",
      "0    10\n",
      "1    11\n",
      "4    14\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Drop丢弃指定轴上的项\n",
    "se1=pd.Series(range(10,15))\n",
    "print(se1)\n",
    "print(se1.drop([2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "d    4\n",
      "dtype: int64\n",
      "a    100\n",
      "b      2\n",
      "c      3\n",
      "d      4\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "#修改某个位置的值 \n",
    "sel =  Series(data = [1,2,3,4], index = list('abcd'))\n",
    "print(sel)\n",
    "sel[0] = 100 \n",
    "print(sel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4Series 进行算术运算操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "London      1\n",
      "HongKong    2\n",
      "Humbai      3\n",
      "lagos       4\n",
      "dtype: int64\n",
      "London    1\n",
      "Accra     3\n",
      "lagos     6\n",
      "Delhi     4\n",
      "dtype: int64\n",
      "Accra       NaN\n",
      "Delhi       NaN\n",
      "HongKong    NaN\n",
      "Humbai      NaN\n",
      "London      0.0\n",
      "lagos      -2.0\n",
      "dtype: float64\n",
      "Accra        NaN\n",
      "Delhi        NaN\n",
      "HongKong     NaN\n",
      "Humbai       NaN\n",
      "London       2.0\n",
      "lagos       10.0\n",
      "dtype: float64\n",
      "Accra        NaN\n",
      "Delhi        NaN\n",
      "HongKong     NaN\n",
      "Humbai       NaN\n",
      "London       1.0\n",
      "lagos       24.0\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "对 Series 的算术运算都是基于 index 进行的。\n",
    "我们可以用加减乘除（+ - * /）这样的运算符对两个 Series 进行运算，\n",
    "Pandas 将会根据索引 index，对响应的数据进行计算，结果将会以浮点数的形式存储，以避免丢失精度。\n",
    "如果 Pandas 在两个 Series 里找不到相同的 index，对应的位置就返回一个空值 NaN\n",
    "'''\n",
    "series1 = pd.Series([1,2,3,4],['London','HongKong','Humbai','lagos'])\n",
    "series2 = pd.Series([1,3,6,4],['London','Accra','lagos','Delhi']) \n",
    "print(series1)\n",
    "print(series2)\n",
    "print(series1-series2)\n",
    "print(series1+series2)\n",
    "print(series1*series2)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.5支持numpy的数组运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b    6\n",
      "d    5\n",
      "dtype: int64\n",
      "a     2\n",
      "b    12\n",
      "c     6\n",
      "d    10\n",
      "dtype: int64\n",
      "a     1\n",
      "b    36\n",
      "c     9\n",
      "d    25\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "sel =  Series(data = [1,6,3,5], index = list('abcd'))\n",
    "print(sel[sel>3])\n",
    "print(sel*2) \n",
    "print(np.square(sel)) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.DataFrame对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 DataFrame的创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   a  b  c  d\n",
      "1  7  9  6  4\n",
      "2  5  4  8  8\n",
      "3  9  4  1  5\n",
      "4  2  0  3  4\n"
     ]
    }
   ],
   "source": [
    "# 1. 创建DataFrame\n",
    "# 使用二维数组\n",
    "df1 = DataFrame(np.random.randint(0,10,(4,4)),index=[1,2,3,4],columns=['a','b','c','d'])\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    Province  pop  year\n",
      "1  Guangdong  1.3  2018\n",
      "2    Beijing  2.5  2018\n",
      "3    Qinghai  1.1  2018\n",
      "4     Fujian  0.7  2018\n"
     ]
    }
   ],
   "source": [
    "# 使用字典创建(行索引由index决定，列索引由字典的键决定)\n",
    "dict={\n",
    "    'Province': ['Guangdong', 'Beijing', 'Qinghai', 'Fujian'],\n",
    "    'pop': [1.3, 2.5, 1.1, 0.7],\n",
    "    'year': [2018, 2018, 2018, 2018]}\n",
    "df2=pd.DataFrame(dict,index=[1,2,3,4])\n",
    "print(df2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   a  b\n",
      "0  1  4\n",
      "1  2  5\n",
      "2  3  6\n"
     ]
    }
   ],
   "source": [
    "# 使用from_dict\n",
    "dict3={\"a\":[1,2,3],\"b\":[4,5,6]}\n",
    "df3=pd.DataFrame.from_dict(dict3)\n",
    "print(df3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  Name Age country\n",
      "a   zs  10      中国\n",
      "b   ls  20      韩国\n",
      "c   we  30      日本\n",
      "d  NaN  40     NaN\n",
      "{'Name': {'a': 'zs', 'b': 'ls', 'c': 'we', 'd': nan}, 'Age': {'a': '10', 'b': '20', 'c': '30', 'd': '40'}, 'country': {'a': '中国', 'b': '韩国', 'c': '日本', 'd': nan}}\n"
     ]
    }
   ],
   "source": [
    "#索引相同的情况下，相同索引的值会相对应，缺少的值会添加NaN\n",
    "data = {\n",
    "    'Name':pd.Series(['zs','ls','we'],index=['a','b','c']),\n",
    "    'Age':pd.Series(['10','20','30','40'],index=['a','b','c','d']),\n",
    "    'country':pd.Series(['中国','日本','韩国'],index=['a','c','b'])\n",
    "}\n",
    "\n",
    "df4 = pd.DataFrame(data)\n",
    "print(df4)\n",
    "\n",
    "\n",
    "dictdata = df4.to_dict()\n",
    "print(dictdata)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 DataFrame对象常用属性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.1基本属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       name age national\n",
      "0     James  18       us\n",
      "1     Curry  20    China\n",
      "2  Iversion  19       us\n",
      "(3, 3)\n",
      "['0', '1', '2']\n",
      "['name', 'age', 'national']\n",
      "name        object\n",
      "age         object\n",
      "national    object\n",
      "dtype: object\n",
      "2\n",
      "[['James' '18' 'us']\n",
      " ['Curry' '20' 'China']\n",
      " ['Iversion' '19' 'us']]\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 3 entries, 0 to 2\n",
      "Data columns (total 3 columns):\n",
      " #   Column    Non-Null Count  Dtype \n",
      "---  ------    --------------  ----- \n",
      " 0   name      3 non-null      object\n",
      " 1   age       3 non-null      object\n",
      " 2   national  3 non-null      object\n",
      "dtypes: object(3)\n",
      "memory usage: 96.0+ bytes\n",
      "None\n",
      "    name age national\n",
      "0  James  18       us\n",
      "1  Curry  20    China\n",
      "       name age national\n",
      "2  Iversion  19       us\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from pandas import Series,DataFrame\n",
    "import numpy as np\n",
    "\n",
    "# dataframe常用属性\n",
    "df_dict = {\n",
    "    'name':['James','Curry','Iversion'],\n",
    "    'age':['18','20','19'],\n",
    "    'national':['us','China','us']\n",
    "}\n",
    "df = pd.DataFrame(data=df_dict,index=['0','1','2'])\n",
    "print(df)\n",
    "# 获取行数和列数\n",
    "print(df.shape)\n",
    "# (3, 3)\n",
    "# 获取行索引\n",
    "print(df.index.tolist())\n",
    "# ['0', '1', '2']\n",
    "# 获取列索引\n",
    "print(df.columns.tolist())\n",
    "# ['name', 'age', 'national']\n",
    "# 获取数据的类型\n",
    "print(df.dtypes)\n",
    "# name        object\n",
    "# age         object\n",
    "# national    object\n",
    "# 获取数据的维度\n",
    "print(df.ndim)\n",
    "# 2 \n",
    "# values属性也会以二维ndarray的形式返回DataFrame的数据\n",
    "print(df.values)\n",
    "# [['James' '18' 'us']\n",
    "#  ['Curry' '20' 'China']\n",
    "#  ['Iversion' '19' 'us']]\n",
    "# 展示df的概览\n",
    "print(df.info())\n",
    "\n",
    "# 显示头几行,默认显示5行\n",
    "print(df.head(2))\n",
    "\n",
    "# 显示后几行\n",
    "print(df.tail(1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.2获取行列的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0       James\n",
      "1       Curry\n",
      "2    Iversion\n",
      "Name: name, dtype: object\n",
      "<class 'pandas.core.series.Series'>\n",
      "       name age\n",
      "0     James  18\n",
      "1     Curry  20\n",
      "2  Iversion  19\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "********************\n",
      "获取多行\n",
      "    name age national\n",
      "0  James  18       us\n",
      "       name age national\n",
      "1     Curry  20    China\n",
      "2  Iversion  19       us\n",
      "********************\n",
      "获取多行多列\n",
      "       name age\n",
      "1     Curry  20\n",
      "2  Iversion  19\n"
     ]
    }
   ],
   "source": [
    "# 获取DataFrame的列\n",
    "print(df['name'])\n",
    "#因为我们只获取一列，所以返回的就是一个 Series\n",
    "print(type(df['name']))\n",
    "\n",
    "# 如果获取多个列，那返回的就是一个 DataFrame 类型：\n",
    "print(df[['name','age']])\n",
    "print(type(df[['name','age']]))\n",
    "\n",
    "print(\"*\"*20)\n",
    "print(\"获取多行\")\n",
    "# 获取一行\n",
    "print(df[0:1])\n",
    "\n",
    "# 去多行\n",
    "print(df[1:3])\n",
    "\n",
    "print(\"*\"*20)\n",
    "print(\"获取多行多列\") \n",
    "# 取多行里面的某一列（不能进行多行多列的选择）\n",
    "# 不能进行多行多列的选择; 可以先取出某些行, 再取列\n",
    "print(df[1:3][['name','age']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.3通过标签索引获取数据loc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       name age national\n",
      "0     James  18       us\n",
      "1     Curry  20    China\n",
      "2  Iversion  19       us\n",
      "James\n",
      "name        James\n",
      "age            18\n",
      "national       us\n",
      "Name: 0, dtype: object\n",
      "name    James\n",
      "age        18\n",
      "Name: 0, dtype: object\n",
      "       name national\n",
      "0     James       us\n",
      "2  Iversion       us\n",
      "       name national\n",
      "0     James       us\n",
      "1     Curry    China\n",
      "2  Iversion       us\n"
     ]
    }
   ],
   "source": [
    "print(df)\n",
    "# 获取某一行某一列的数据\n",
    "print(df.loc['0','name'])\n",
    "\n",
    "# 一行所有列\n",
    "print(df.loc['0',:])\n",
    "\n",
    "# 某一行多列的数据\n",
    "print(df.loc['0',['name','age']])\n",
    "\n",
    "# 选择间隔的多行多列\n",
    "print(df.loc[['0','2'],['name','national']])\n",
    "# 选择连续的多行和间隔的多列\n",
    "print(df.loc['0':'2',['name','national']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.4通过位置获取数据iloc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name        Iversion\n",
      "age               19\n",
      "national          us\n",
      "Name: 2, dtype: object\n",
      "       name age national\n",
      "1     panda  20    China\n",
      "2  Iversion  19       us\n",
      "    name age national\n",
      "1  panda  20    China\n",
      "0  panda  18       us\n",
      "1    20\n",
      "2    19\n",
      "0    18\n",
      "Name: age, dtype: object\n",
      "Iversion\n",
      "       name age national\n",
      "1     panda  20    China\n",
      "2  Iversion  19       us\n",
      "0     panda  18       us\n",
      "       name age national\n",
      "0     panda  18       us\n",
      "2  Iversion  19       us\n",
      "1     panda  20    China\n"
     ]
    }
   ],
   "source": [
    "# 取一行\n",
    "print(df.iloc[1])\n",
    "\n",
    "# 取连续多行\n",
    "print(df.iloc[0:2])\n",
    "\n",
    "# 取间断的多行\n",
    "print(df.iloc[[0,2],:])\n",
    "\n",
    "# 取某一列\n",
    "print(df.iloc[:,1])\n",
    "\n",
    "# 某一个值\n",
    "print(df.iloc[1,0])\n",
    "\n",
    "# 修改值\n",
    "df.iloc[0,0]='panda'\n",
    "print(df)\n",
    "\n",
    "df = df.sort_values(by='age',ascending=True)\n",
    "print(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.3 dataframe修改index、columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    a  b  c\n",
      "bj  0  1  2\n",
      "sh  3  4  5\n",
      "gz  6  7  8\n",
      "Index(['bj', 'sh', 'gz'], dtype='object')\n",
      "           a  b  c\n",
      "beijing    0  1  2\n",
      "shanghai   3  4  5\n",
      "guangzhou  6  7  8\n"
     ]
    }
   ],
   "source": [
    "df1 = pd.DataFrame(np.arange(9).reshape(3, 3), index = ['bj', 'sh', 'gz'], columns=['a', 'b', 'c'])\n",
    "print(df1) \n",
    "\n",
    "# 暴力方法\n",
    "# 修改 df1 的 index\n",
    "print(df1.index) # 可以打印出print的值，同时也可以为其赋值\n",
    "df1.index = ['beijing', 'shanghai', 'guangzhou']\n",
    "print(df1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a_ABC  b_ABC  c_ABC\n",
      "beijing_ABC        0      1      2\n",
      "shanghai_ABC       3      4      5\n",
      "guangzhou_ABC      6      7      8\n",
      "               a_ABC  b_ABC  c_ABC\n",
      "beijing_ABC        0      1      2\n",
      "shanghai_ABC       3      4      5\n",
      "guangzhou_ABC      6      7      8\n"
     ]
    }
   ],
   "source": [
    "#温柔方法 rename inplace\n",
    "# 自定义map函数（x是原有的行列值）\n",
    "def test_map(x):  \n",
    "    return x+'_ABC'\n",
    "# inplace：布尔值，默认为False。指定是否返回新的DataFrame。如果为True，则在原df上修改，返回值为None。\n",
    "df1copy = df1.rename(index=test_map, columns=test_map, inplace=False)\n",
    "print(df1copy)\n",
    "df1.rename(index=test_map, columns=test_map, inplace=True)\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    a  b  c\n",
      "bj  0  1  2\n",
      "sh  3  4  5\n",
      "gz  6  7  8\n",
      "         aa  b  c\n",
      "beijing   0  1  2\n",
      "sh        3  4  5\n",
      "gz        6  7  8\n"
     ]
    }
   ],
   "source": [
    "#修改某个/某些索引. \n",
    "df1 = pd.DataFrame(np.arange(9).reshape(3, 3), index = ['bj', 'sh', 'gz'], columns=['a', 'b', 'c'])\n",
    "print(df1) \n",
    "# 同时，rename 还可以传入字典，为某个 index 单独修改名称\n",
    "df3 = df1.rename(index={'bj':'beijing'}, columns = {'a':'aa'}) \n",
    "print(df3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   X  Y  S  Z\n",
      "0  0  0  a  1\n",
      "1  1  1  b  1\n",
      "2  2  2  c  2\n",
      "3  3  3  d  2\n",
      "4  4  4  e  2\n",
      "   X  Y  S  Z\n",
      "a  0  0  a  1\n",
      "b  1  1  b  1\n",
      "c  2  2  c  2\n",
      "d  3  3  d  2\n",
      "e  4  4  e  2\n"
     ]
    }
   ],
   "source": [
    " # 列转化为索引\n",
    "df1=pd.DataFrame({'X':range(5),'Y':range(5),'S':list(\"abcde\"),'Z':[1,1,2,2,2]})\n",
    "print(df1)\n",
    "# 指定一列为索引 (drop=False 指定同时保留作为索引的列)\n",
    "# drop=True 丢弃该列  \n",
    "result = df1.set_index('S',drop=False)\n",
    "result.index.name=None  \n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   X  Y  S  Z\n",
      "0  0  0  a  1\n",
      "1  1  1  b  1\n",
      "2  2  2  c  2\n",
      "3  3  3  d  2\n",
      "4  4  4  e  2\n",
      "   0  0  a  1\n",
      "0  0  0  a  1\n",
      "1  1  1  b  1\n",
      "2  2  2  c  2\n",
      "3  3  3  d  2\n",
      "4  4  4  e  2\n"
     ]
    }
   ],
   "source": [
    "# 行转为列索引\n",
    "df1=pd.DataFrame({'X':range(5),'Y':range(5),'S':list(\"abcde\"),'Z':[1,1,2,2,2]})\n",
    "print(df1)\n",
    "result = df1.set_axis(df1.iloc[0],axis=1,inplace=False)\n",
    "result.columns.name=None\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.4 添加数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     name gender  age  score\n",
      "0    Snow      M   22     80\n",
      "1  Tyrion      M   32     98\n",
      "2   Sansa      F   18     67\n",
      "3    Arya      F   14     90\n",
      "0      Snow\n",
      "1    Tyrion\n",
      "2     Sansa\n",
      "3      Arya\n",
      "Name: name, dtype: object\n",
      "     name gender  age  score city\n",
      "0    Snow      M   22     80   北京\n",
      "1  Tyrion      M   32     98   山西\n",
      "2   Sansa      F   18     67   湖北\n",
      "3    Arya      F   14     90   澳门\n",
      "     name gender  age  score city\n",
      "0    Snow      M   22     80   北京\n",
      "1  Tyrion      M   32     98   山西\n",
      "2   Sansa      F   18     67   湖北\n",
      "3    Arya      F   14     90   澳门\n"
     ]
    }
   ],
   "source": [
    "# 增加列数据\n",
    "df1 = pd.DataFrame([['Snow','M',22],['Tyrion','M',32],['Sansa','F',18],['Arya','F',14]],\n",
    "                   columns=['name','gender','age'])\n",
    "\n",
    "# 在数据框最后加上score一列\n",
    "df1['score']=[80,98,67,90]   \n",
    "print(df1) \n",
    "print(df1.name) \n",
    "#添加一列 \n",
    "df1['city']=['北京','山西','湖北','澳门']   # 给city列赋值\n",
    "print(df1)\n",
    "\n",
    "\n",
    "df1['city']=['北京','山西','湖北','澳门']   # 给city列赋值\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     name gender  scoreB  scoreA  age  score city\n",
      "0    Snow      M      80      80   22     80   北京\n",
      "1  Tyrion      M      98      98   32     98   山西\n",
      "2   Sansa      F      67      67   18     67   湖北\n",
      "3    Arya      F      90      90   14     90   澳门\n"
     ]
    }
   ],
   "source": [
    "# df中的insert,插入一列\n",
    "'''\n",
    "df.insert(iloc,column,value)\n",
    "iloc:要插入的位置\n",
    "colunm:列名\n",
    "value:值\n",
    "'''\n",
    "#插入的列名不能与原先列名相同.新列名\n",
    "df1.insert(2,'scoreB',[80,98,67,90])\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     name gender  age\n",
      "0    Snow      M   22\n",
      "1  Tyrion      M   32\n",
      "2   Sansa      F   18\n",
      "3    Arya      F   14\n",
      "    name gender  age\n",
      "0   Snow      M   22\n",
      "1    111    222  333\n",
      "2  Sansa      F   18\n",
      "3   Arya      F   14\n"
     ]
    }
   ],
   "source": [
    "# 修改行数据\n",
    "df1 = pd.DataFrame([['Snow','M',22],['Tyrion','M',32],['Sansa','F',18],['Arya','F',14]],\n",
    "                   columns=['name','gender','age'])\n",
    "print(df1)\n",
    "row=['111','222','333']\n",
    "df1.iloc[1]=row\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     name gender  age\n",
      "0    Snow      M   22\n",
      "1  Tyrion      M   32\n",
      "2   Sansa      F   18\n",
      "3    Arya      F   14\n",
      "   name gender  age\n",
      "0  lisa      F   19\n",
      "     name gender  age\n",
      "0    Snow      M   22\n",
      "1  Tyrion      M   32\n",
      "2   Sansa      F   18\n",
      "3    Arya      F   14\n",
      "4    lisa      F   19\n"
     ]
    }
   ],
   "source": [
    "# 增加行数据\n",
    "df1 = pd.DataFrame([['Snow','M',22],['Tyrion','M',32],['Sansa','F',18],['Arya','F',14]],\n",
    "                   columns=['name','gender','age'])\n",
    "\n",
    "print(df1)\n",
    "# 先创建一个DataFrame，用来增加进数据框的最后一行\n",
    "new=pd.DataFrame({'name':'lisa',\n",
    "                  'gender':'F',\n",
    "                  'age':19\n",
    "                  },index=[0])\n",
    "print(new)\n",
    "df1=df1.append(new,ignore_index=True)  \n",
    "print(df1) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   one  two  three\n",
      "0    0    1      2\n",
      "1    3    4      5\n",
      "2    6    7      8\n",
      "   two  three\n",
      "0    1      2\n",
      "1    4      5\n",
      "2    7      8\n",
      "   two  three\n",
      "2    7      8\n"
     ]
    }
   ],
   "source": [
    "# DataFrame的删除\n",
    "'''\n",
    "lables：要删除数据的标签\n",
    "axis：0表示删除行，1表示删除列，默认0\n",
    "inplace:是否在当前df中执行此操作\n",
    "'''\n",
    "df2 = pd.DataFrame(np.arange(9).reshape(3,3),columns=['one','two','three'])\n",
    "print(df2)\n",
    "df3=df2.drop(['one'],axis=1, inplace=True)\n",
    "df3=df2.drop([0,1],axis=0, inplace=False)\n",
    "print(df2)\n",
    "print(df3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 数据处理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.1 查看缺失值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    4.0\n",
      "1    NaN\n",
      "2    8.0\n",
      "3    NaN\n",
      "4    5.0\n",
      "dtype: float64\n",
      "0    4.0\n",
      "2    8.0\n",
      "4    5.0\n",
      "dtype: float64\n",
      "0     True\n",
      "1    False\n",
      "2     True\n",
      "3    False\n",
      "4     True\n",
      "dtype: bool\n",
      "0    False\n",
      "1     True\n",
      "2    False\n",
      "3     True\n",
      "4    False\n",
      "dtype: bool\n",
      "0    4.0\n",
      "2    8.0\n",
      "4    5.0\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "from numpy import nan as NaN\n",
    "se=pd.Series([4,NaN,8,NaN,5]) \n",
    "print(se)\n",
    "print(se.dropna())   # 删除缺失值\n",
    "print(se.notnull())  \n",
    "print(se.isnull())    \n",
    "print(se[se.notnull()])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.2删除缺失值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  NaN  2.0\n",
      "2  NaN  NaN  NaN\n",
      "3  8.0  8.0  NaN\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  NaN  2.0\n",
      "3  8.0  8.0  NaN\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  NaN  2.0\n",
      "2  NaN  NaN  NaN\n",
      "3  8.0  8.0  NaN\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  NaN  2.0\n",
      "3  8.0  8.0  NaN\n"
     ]
    }
   ],
   "source": [
    "#处理DataFrame对象\n",
    "df1=pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])\n",
    "print(df1)\n",
    "\n",
    "# 默认滤除所有包含NaN：\n",
    "print(df1.dropna())\n",
    "\n",
    "# 传入how=‘all’滤除全为NaN的行：\n",
    "print(df1.dropna(how='all')) # 默认情况下是how='any'，只要有nan就删除\n",
    "\n",
    "# 传入axis=1滤除列：\n",
    "print(df1.dropna(axis=1,how=\"all\"))\n",
    "\n",
    "#传入thresh=n保留至少有n个非NaN数据的行：\n",
    "print(df1.dropna(thresh=1))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.3 填充缺失数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  NaN  2.0\n",
      "2  NaN  NaN  NaN\n",
      "3  8.0  8.0  NaN\n",
      "      0     1     2\n",
      "0   1.0   2.0   3.0\n",
      "1  10.0  20.0   2.0\n",
      "2  10.0  20.0  30.0\n",
      "3   8.0   8.0  30.0\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  4.5  5.0  2.0\n",
      "2  4.5  5.0  2.5\n",
      "3  8.0  8.0  2.5\n",
      "None\n",
      "     0    1    2\n",
      "0  1.0  2.0  3.0\n",
      "1  NaN  5.0  2.0\n",
      "2  NaN  5.0  NaN\n",
      "3  8.0  8.0  NaN\n"
     ]
    }
   ],
   "source": [
    "df1=pd.DataFrame([[1,2,3],[NaN,NaN,2],[NaN,NaN,NaN],[8,8,NaN]])\n",
    "print(df1)\n",
    "\n",
    "# # 用常数填充fillna\n",
    "# print(df1.fillna(0))\n",
    "\n",
    "# #传入inplace=True直接修改原对象：\n",
    "# df1.fillna(0,inplace=True)\n",
    "# print(df1)\n",
    "\n",
    "# 通过字典填充不同的常数\n",
    "print(df1.fillna({0:10,1:20,2:30})) \n",
    "\n",
    "# 填充平均值\n",
    "print(df1.fillna(df1.mean()))\n",
    "# 如果只填充一列  #第1列 \n",
    "print(df1.iloc[:,1].fillna(5,inplace = True))\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   0  1  2    3    4\n",
      "0  5  6  3  8.0  0.0\n",
      "1  0  8  5  NaN  3.0\n",
      "2  8  8  5  NaN  NaN\n",
      "3  6  3  8  NaN  NaN\n",
      "4  8  2  3  6.0  4.0\n",
      "   0  1  2    3    4\n",
      "0  5  6  3  8.0  0.0\n",
      "1  0  8  5  8.0  3.0\n",
      "2  8  8  5  8.0  3.0\n",
      "3  6  3  8  8.0  3.0\n",
      "4  8  2  3  6.0  4.0\n",
      "   0  1  2    3    4\n",
      "0  5  6  3  8.0  0.0\n",
      "1  0  8  5  NaN  3.0\n",
      "2  8  8  5  NaN  NaN\n",
      "3  6  3  8  6.0  4.0\n",
      "4  8  2  3  6.0  4.0\n",
      "     0    1    2    3    4\n",
      "0  5.0  6.0  3.0  8.0  0.0\n",
      "1  0.0  8.0  5.0  5.0  3.0\n",
      "2  8.0  8.0  5.0  5.0  NaN\n",
      "3  6.0  3.0  8.0  8.0  NaN\n",
      "4  8.0  2.0  3.0  6.0  4.0\n"
     ]
    }
   ],
   "source": [
    "df2=pd.DataFrame(np.random.randint(0,10,(5,5)))\n",
    "df2.iloc[1:4,3]=NaN  #第1行到第4行,第3列\n",
    "df2.iloc[2:4,4]=NaN  #第2行到第4行,第4列\n",
    "print(df2)\n",
    "\n",
    "#用前面的值来填充ffill   用后面的值来填充bfill  前后默认按照0轴方向 上下 , 当前后无值,不填写. \n",
    "print(df2.fillna(method='ffill'))\n",
    "\n",
    "# 传入limit=” “限制填充行数：\n",
    "print(df2.fillna(method='bfill',limit=1))\n",
    "\n",
    "# 传入axis=” “修改填充方向：\n",
    "# 默认上下填充，如果想左右填充，需要制定轴 传入axis=” “修改填充方向： \n",
    "print(df2.fillna(method=\"ffill\",limit=1,axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.4 移除重复数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   A  B\n",
      "0  1  a\n",
      "1  1  a\n",
      "2  1  b\n",
      "3  2  b\n",
      "4  2  b\n",
      "5  3  c\n",
      "6  1  a\n",
      "0    False\n",
      "1     True\n",
      "2    False\n",
      "3    False\n",
      "4     True\n",
      "5    False\n",
      "6     True\n",
      "dtype: bool\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "DataFrame中经常会出现重复行，利用duplicated()函数返回每一行判断是否重复的结果（重复则为True)\n",
    "'''\n",
    "df1=pd.DataFrame({'A':[1,1,1,2,2,3,1],'B':list(\"aabbbca\")})\n",
    "print(df1)\n",
    "\n",
    "print(df1.duplicated()) \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   A  B\n",
      "0  1  a\n",
      "2  1  b\n",
      "3  2  b\n",
      "5  3  c\n"
     ]
    }
   ],
   "source": [
    "# 去除全部的重复行\n",
    "print(df1.drop_duplicates())\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   A  B\n",
      "0  1  a\n",
      "3  2  b\n",
      "5  3  c\n"
     ]
    }
   ],
   "source": [
    "# 指定列去除重复行\n",
    "print(df1.drop_duplicates(['A']))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   A  B\n",
      "4  2  b\n",
      "5  3  c\n",
      "6  1  a\n",
      "   A  B\n",
      "0  1  a\n",
      "2  1  b\n",
      "3  2  b\n",
      "5  3  c\n"
     ]
    }
   ],
   "source": [
    "\n",
    "#保留重复行中的最后一行\n",
    "print(df1.drop_duplicates(['A'],keep='last'))\n",
    "\n",
    "# 去除重复的同时改变DataFrame对象\n",
    "df1.drop_duplicates(['A','B'],inplace=True)\n",
    "print(df1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
